//@author A0103459H
#include "Task.h"
#include <string>

Task::Task() {
}


Task::Task(string taskName, string StartTime, string EndTime, string Venue)
{
	_TaskName = taskName;
	_StartTime = StartTime;
	_EndTime = EndTime;
	_Venue = Venue;
	_isDone = false;
	_TaskType = determineTaskType();

	_start = createDateTimefromString (_StartTime);
	_end = createDateTimefromString (_EndTime);
}

Task::~Task(void)
{
}

string Task::getTaskName() {
	return _TaskName;
}

string Task::getStartTime() {
	return _StartTime;
}

string Task::getEndTime() {
	return _EndTime;
}

string Task::getVenue() {
	return _Venue;
}

bool Task::getIsDone() {
	return _isDone;
}

string Task::getStatus() {
	if (_isDone) {
		return "Task Completed";	//refactor: magic string
	} else {
		return "To be Done.";
	}
}

int Task::getTaskType() {
	return _TaskType;
}

void Task::setTaskName(string taskName) {
	_TaskName = taskName;
	return;
}

void Task::setStartTime(string startTimeString) {
	_StartTime = startTimeString;
	return;
}

void Task::setEndTime(string endTimeString){
	_EndTime = endTimeString;
	return;
}

void Task::setVenue(string Venue){
	_Venue = Venue;
	return;
}

void Task::setStatus(string status){
	if (status == "Task Completed") {		//magic string refactor
		_isDone = true;
	} else if (status == "To be Done.") {    //Quang's changes. Magic string inconsistent. I was not able to cout properly
		_isDone = false;
	} else {
		// return error.
	}
	return;
}

void Task::setTaskType() {
	_TaskType = determineTaskType();
}

int Task::determineTaskType() {

	bool isStartTime = (_StartTime !="");
	bool isEndTime = (_EndTime != "");

	if (isStartTime) {
		if (isEndTime) {
			return TIMED_TASK;
		} 
	} else if (isEndTime) {
		return DEADLINE_TASK;
	} else {
		return FLOATING_TASK;
	}
}

string Task::outputAllTaskInfo() {
	//requires high refactoring
	ostringstream toUser;
	string taskname;

	//toUser << "==================================================================" << endl;
	////toUser << "Task Id	  : " << i << endl;
	//toUser << "Task Name	: " << _TaskName << endl;
	//toUser << "Start Time	: " << _StartTime << endl;
	//toUser << "End Time	: " << _EndTime << endl;
	//toUser << "Venue		: " << _Venue << endl;
	//toUser << "Status		: " << getStatus() << endl;
	//toUser << "==================================================================" << endl <<endl;

	if (_TaskName.size() > 20) {
		taskname = _TaskName.substr(0, 17) + "...";
	} else {
		taskname = _TaskName;
	}

	toUser<<setw(25)<<left<<taskname<<setw(20)<<left<<_StartTime.substr(0,16)<<setw(20)<<left<<_EndTime.substr(0,16)<<(_isDone?"Done":"ToDo") << endl;

	return toUser.str();
}

//@author A0101878B

bool Task::isClashingWith(Task another){
	bool startClash = false;
	bool endClash = false;
	bool spanClash = false;
	_start = createDateTimefromString(_StartTime);
	_end = createDateTimefromString (_EndTime);
	if(another.getStart().compareTo(_start) >= 0 && another.getStart().compareTo(_end) < 0)
		startClash = true;

	if(another.getEnd().compareTo(_start) > 0 && another.getEnd().compareTo(_end) <= 0)
		endClash = true;

	if(another.getStart().compareTo(_start) <= 0 && another.getEnd().compareTo(_end) >= 0)
		spanClash = true;

	return startClash || endClash || spanClash;
}

DateTime Task::createDateTimefromString (string input) {
	try{
			std::replace(input.begin(),input.end(),':',' ');
			std::replace(input.begin(),input.end(),'/',' ');
		}
	 catch (std::exception& e){

	}
	istringstream inputStream(input);

	int day, month, year, hour, minute, second;
	string dayName;
	string monthName;

	inputStream >> dayName >> monthName >> day >> hour >> minute >> second >> year;
	//inputStream >> day >>month >>year >> hour >> minute >> second;
	string monthNames [] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

	for (int i = 0; i < 12; i++) {
		if (monthName == monthNames[i]) {
			month = i+1;
		}
	}

	DateTime dateTimeObj(year, month, day, hour, minute);
	return dateTimeObj;
}

DateTime Task ::getStart(){
	return createDateTimefromString (_StartTime);
}

DateTime Task::getEnd(){
	return createDateTimefromString (_EndTime);
}

bool Task::operator<(Task& a){
	
	if(a.getTaskType() == TIMED_TASK)
		return (_start.compareTo(a.getStart()) < 0);
	else if(a.getTaskType() == DEADLINE_TASK)
		return (_end.compareTo(a.getEnd()) < 0);
	else
		return false;
}